﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing.Design;
using Water.Resources.Globalize;
using System.Globalization;
using System.Collections;
using Water.Web.JSON;

[assembly: WebResource("Water.Resources.Default.JS.Accordion.jquery.accordion.js", "text/javascript")]
namespace Water.Web.Controls
{
    [ToolboxData("<{0}:Accordion runat=server></{0}:Accordion>")]
    /*[Designer("Water.Web.Controls.Design.AccordionControlDesigner")]*/
    public class Accordion:HierarchicalDataBoundControl
    {
        private bool dataBound;
        private string currentSiteMapNodeDataPath;
        private TreeNode rootNode;
        private string defaultNavigateImageUrl = Path.ResourcePath + "Images/Accordion/defaultarrow.png";
        private string defaultTilteImageUrl = Path.ResourcePath + "Images/Arrow/arrow_right_b.png";
        private string defaultTarget = "_blank";
        private Hashtable ht = new Hashtable();


        [Category("Behavior"), GlobalizeDescription("Accordion_Target"), DefaultValue(false)]
        public string Target
        {
            get { return defaultTarget; }
            set { defaultTarget = value; }
        } 

        [DefaultValue(""), Category("Data"), GlobalizeDescription("Accordion_TextFormatString"), Localizable(true)]
        public string TextFormatString
        {
            get
            {
                string str = (string)this.ViewState["TextFormatString"];
                if (str == null)
                {
                    return string.Empty;
                }
                return str;
            }
            set
            {
                this.ViewState["TextFormatString"] = value;
            }
        }

        [DefaultValue(""), Category("Data"), GlobalizeDescription("Accordion_NavigateUrlFormatString"), Localizable(true)]
        public string NavigateUrlFormatString
        {
            get
            {
                string str = (string)this.ViewState["NavigateUrlFormatString"];
                if (str == null)
                {
                    return string.Empty;
                }
                return str;
            }
            set
            {
                this.ViewState["NavigateUrlFormatString"] = value;
            }
        }

        [DefaultValue(""), Category("Data"), GlobalizeDescription("Accordion_LeafTextFormatString"), Localizable(true)]
        public string LeafTextFormatString
        {
            get
            {
                string str = (string)this.ViewState["LeafTextFormatString"];
                if (str == null)
                {
                    return string.Empty;
                }
                return str;
            }
            set
            {
                this.ViewState["LeafTextFormatString"] = value;
            }
        }

        [DefaultValue(""), Category("Data"), GlobalizeDescription("Accordion_LeafNavigateUrlFormatString"), Localizable(true)]
        public string LeafNavigateUrlFormatString
        {
            get
            {
                string str = (string)this.ViewState["LeafNavigateUrlFormatString"];
                if (str == null)
                {
                    return string.Empty;
                }
                return str;
            }
            set
            {
                this.ViewState["LeafNavigateUrlFormatString"] = value;
            }
        }

        [GlobalizeDescription("ImageToolTipField"), DefaultValue(""), Category("Data"), TypeConverter("System.Web.UI.Design.DataSourceViewSchemaConverter")]
        public string ImageToolTipField
        {
            get
            {
                string str = (string)this.ViewState["ImageToolTipField"];
                if (str == null)
                {
                    return string.Empty;
                }
                return str;
            }
            set
            {
                this.ViewState["ImageToolTipField"] = value;
            }
        }

        [DefaultValue(""), Category("Data"), GlobalizeDescription("ImageUrlField"), TypeConverter("System.Web.UI.Design.DataSourceViewSchemaConverter")]
        public string ImageUrlField
        {
            get
            {
                string str = (string)this.ViewState["ImageUrlField"];
                if (str == null)
                {
                    return string.Empty;
                }
                return str;
            }
            set
            {
                this.ViewState["ImageUrlField"] = value;
            }
        }

        [Category("Data"), DefaultValue(""), GlobalizeDescription("NavigateUrlField"), TypeConverter("System.Web.UI.Design.DataSourceViewSchemaConverter")]
        public string NavigateUrlField
        {
            get
            {
                string str = (string)this.ViewState["NavigateUrlField"];
                if (str == null)
                {
                    return string.Empty;
                }
                return str;
            }
            set
            {
                this.ViewState["NavigateUrlField"] = value;
            }
        }

        [Category("Data"), TypeConverter("System.Web.UI.Design.DataSourceViewSchemaConverter"), GlobalizeDescription("TargetField"), DefaultValue("")]
        public string TargetField
        {
            get
            {
                string str = (string)this.ViewState["TargetField"];
                if (str == null)
                {
                    return string.Empty;
                }
                return str;
            }
            set
            {
                this.ViewState["TargetField"] = value;
            }
        }

        [Category("Data"), GlobalizeDescription("TextField"), DefaultValue(""), TypeConverter("System.Web.UI.Design.DataSourceViewSchemaConverter")]
        public string TextField
        {
            get
            {
                string str = (string)this.ViewState["TextField"];
                if (str == null)
                {
                    return string.Empty;
                }
                return str;
            }
            set
            {
                this.ViewState["TextField"] = value;
            }
        }

        [DefaultValue(""), TypeConverter("System.Web.UI.Design.DataSourceViewSchemaConverter"), GlobalizeDescription("ToolTipField"), Category("Data")]
        public string ToolTipField
        {
            get
            {
                string str = (string)this.ViewState["ToolTipField"];
                if (str == null)
                {
                    return string.Empty;
                }
                return str;
            }
            set
            {
                this.ViewState["ToolTipField"] = value;
            }
        }

        [GlobalizeDescription("ValueField"), DefaultValue(""), TypeConverter("System.Web.UI.Design.WebControls.TreeNodeCollectionEditor"), Category("Data")]
        public string ValueField
        {
            get
            {
                string str = (string)this.ViewState["ValueField"];
                if (str == null)
                {
                    return string.Empty;
                }
                return str;
            }
            set
            {
                this.ViewState["ValueField"] = value;
            }
        }
 
        internal TreeNode RootNode
        {
            get 
            {
                if (this.rootNode == null)
                    this.rootNode = new TreeNode(string.Empty);
                return rootNode; 
            }
        }

        [GlobalizeDescription("Accordion_Nodes"), PersistenceMode(PersistenceMode.InnerProperty), DefaultValue((string)null), MergableProperty(false), Editor("Water.Web.Controls.Design.AccordionNodeCollectionEditor", typeof(UITypeEditor))]
        public TreeNodeCollection Nodes
        {
            get
            {
                return this.RootNode.ChildNodes;
            }
        }

        private bool expandAll = false;

        [Category("Behavior"), GlobalizeDescription("Accordion_ExpandAll"), DefaultValue(false)]
        public bool ExpandAll
        {
            get
            {
                return expandAll;
            }
            set
            {
                this.expandAll = value;
                JSONSettingUtil.SetHashtable(ht, "expandall", value); 
            }
        }
        private string eventName = "click";

        [Category("Behavior"), GlobalizeDescription("Accordion_Event"), DefaultValue("click")]
        public string Event
        {
            get { return eventName; }
            set 
            { 
                eventName = value;
                JSONSettingUtil.SetHashtable(ht, "event", "'" + value + "'"); 
            }
        }

        private bool displayOnlyOne = false;

        [Category("Behavior"), GlobalizeDescription("Accordion_DisplayOnlyOne"), DefaultValue(false)]
        public bool DisplayOnlyOne
        {
            get { return displayOnlyOne; }
            set 
            { 
                displayOnlyOne = value;
                JSONSettingUtil.SetHashtable(ht, "displayonlyone", value); 
            }
        }
        private int active = -1;

        [Category("Behavior"), GlobalizeDescription("Accordion_Active"), DefaultValue(-1)]
        public int Active
        {
            get { return active; }
            set 
            { 
                active = value;
                JSONSettingUtil.SetHashtable(ht, "active", value); 
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            PageManager.Register(this);
            this.Page.ClientScript.RegisterClientScriptResource(typeof(Accordion), "Water.Resources.Default.JS.Accordion.jquery.accordion.js");
            PageManager.RegisterPageStyleSheet(this, "Accordion_CSS", "CSS/Accordion.css");
        }

        protected override HtmlTextWriterTag TagKey
        {
            get
            {
                return HtmlTextWriterTag.Div;
            }
        }

        protected override void AddAttributesToRender(HtmlTextWriter writer)
        {
            writer.AddAttribute(HtmlTextWriterAttribute.Class, "accordion");
            base.AddAttributesToRender(writer);
        }

        protected override void PerformDataBinding()
        {
            base.PerformDataBinding();
            if ((!base.DesignMode && this.dataBound) && (string.IsNullOrEmpty(this.DataSourceID) && (this.DataSource == null)))
            {
                this.Nodes.Clear();
            }
            else
            {
                this.DataBindNode(this.RootNode);
                if (!string.IsNullOrEmpty(this.DataSourceID) || (this.DataSource != null))
                {
                    this.dataBound = true;
                }
            }

        }

        private void DataBindNode(TreeNode node)
        {
            HierarchicalDataSourceView view = this.GetData(node.DataPath);
            if (base.IsBoundUsingDataSourceID || (this.DataSource != null))
            {
                if (view == null)
                {
                    //throw new InvalidOperationException(/*SR.GetString("TreeView_DataSourceReturnedNullView", new object[] { this.ID })*/);
                }
                IHierarchicalEnumerable enumerable = view.Select();
                node.ChildNodes.Clear();
                if (enumerable != null)
                {
                    if (base.IsBoundUsingDataSourceID)
                    {
                        SiteMapDataSource dataSource = this.GetDataSource() as SiteMapDataSource;
                        if ((dataSource != null) && (this.currentSiteMapNodeDataPath == null))
                        {
                            IHierarchyData currentNode = dataSource.Provider.CurrentNode;
                            if (currentNode != null)
                            {
                                this.currentSiteMapNodeDataPath = currentNode.Path;
                            }
                            else
                            {
                                this.currentSiteMapNodeDataPath = string.Empty;
                            }
                        }
                    }
                    this.DataBindRecursive(node, enumerable);
                }
            }
        }

        private void DataBindRecursive(TreeNode node, IHierarchicalEnumerable enumerable)
        {
            foreach (object obj in enumerable)
            {
                IHierarchyData hierarchyData = enumerable.GetHierarchyData(obj);
                if(null !=hierarchyData)
                {
                    TreeNode newNode = new TreeNode();
                    PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(obj);
                    if (this.TextField.Length > 0)
                    {
                        PropertyDescriptor descriptor = properties.Find(this.TextField, true);
                        if (descriptor != null)
                        {
                            object objTextField = descriptor.GetValue(obj);
                            if (null != objTextField)
                                newNode.Text = objTextField.ToString();
                        }

                    }
                    if (this.NavigateUrlField.Length > 0)
                    {
                        PropertyDescriptor descriptor = properties.Find(this.NavigateUrlField, true);
                        if (descriptor != null)
                        {
                            object objNavigateUrlField = descriptor.GetValue(obj);
                            if (null != objNavigateUrlField)
                                newNode.NavigateUrl = objNavigateUrlField.ToString();
                        }
                    }
                    if (this.ImageUrlField.Length > 0)
                    {
                        PropertyDescriptor descriptor = properties.Find(this.ImageUrlField, true);
                        if (descriptor != null)
                        {
                            object objImageUrlField = descriptor.GetValue(obj);
                            if (null != objImageUrlField)
                                newNode.ImageUrl = objImageUrlField.ToString();
                        }
                    }
                    if (this.TargetField.Length > 0)
                    {
                        PropertyDescriptor descriptor = properties.Find(this.TargetField, true);
                        if (descriptor != null)
                        {
                            object objTargetField = descriptor.GetValue(obj);
                            if (null != objTargetField)
                                newNode.Target = objTargetField.ToString();
                        }
                    }
                    if (this.ValueField.Length > 0)
                    {
                        PropertyDescriptor descriptor = properties.Find(this.ValueField, true);
                        if (descriptor != null)
                        {
                            object objValueField = descriptor.GetValue(obj);
                            if (null != objValueField)
                                newNode.Value = objValueField.ToString();
                        }
                    }
                    if (this.ImageToolTipField.Length > 0)
                    {
                        PropertyDescriptor descriptor = properties.Find(this.ImageToolTipField, true);
                        if (descriptor != null)
                        {
                            object objImageToolTipField = descriptor.GetValue(obj);
                            if (null != objImageToolTipField)
                                newNode.ImageToolTip = objImageToolTipField.ToString();
                        }
                    }
                    if (this.ToolTipField.Length > 0)
                    {
                        PropertyDescriptor descriptor = properties.Find(this.ToolTipField, true);
                        if (descriptor != null)
                        {
                            object objToolTipField = descriptor.GetValue(obj);
                            if (null != objToolTipField)
                                newNode.ToolTip = objToolTipField.ToString();
                        }
                    }

                    node.ChildNodes.Add(newNode);

                    if (!string.IsNullOrEmpty(this.TextFormatString) || !string.IsNullOrEmpty(this.NavigateUrlFormatString))
                    {
                        string[] param = { newNode.Text, newNode.NavigateUrl, newNode.Target, newNode.Value, newNode.Depth.ToString(), (!hierarchyData.HasChildren).ToString().ToLower() };

                        if (!string.IsNullOrEmpty(this.TextFormatString))
                        { 
                            newNode.Text=string.Format(CultureInfo.CurrentCulture,this.TextFormatString,param);  
                        }
                        if (!string.IsNullOrEmpty(this.LeafTextFormatString) && !hierarchyData.HasChildren)
                        {
                            newNode.Text = string.Format(CultureInfo.CurrentCulture, this.LeafTextFormatString, param);
                        }

                        if (!string.IsNullOrEmpty(this.NavigateUrlFormatString))
                        {
                            newNode.NavigateUrl = string.Format(CultureInfo.CurrentCulture, this.NavigateUrlFormatString, param);
                           
                        }
                        if (!string.IsNullOrEmpty(this.LeafNavigateUrlFormatString) && !hierarchyData.HasChildren)
                        {
                            newNode.NavigateUrl = string.Format(CultureInfo.CurrentCulture, this.LeafNavigateUrlFormatString, param);
                        }
                    }
                    

                    if (hierarchyData.HasChildren)
                    {
                        IHierarchicalEnumerable newEnumerable = hierarchyData.GetChildren();
                        if (null != newEnumerable)
                            DataBindRecursive(newNode,newEnumerable);
                    }
                }

            }
        }

        protected override void RenderContents(HtmlTextWriter writer)
        {
            base.RenderContents(writer);
            if (!DesignMode)
            {
                RenderNodeCollection(writer, this.Nodes);
            }
            else
                writer.Write(this.ID);
        }

        private void RenderNodeCollection(HtmlTextWriter writer, TreeNodeCollection nodes)
        {
            foreach (TreeNode node in nodes)
            {
                RenderNode(writer, node);
            }
        }

        private void RenderNode(HtmlTextWriter writer, TreeNode node)
        { 
            bool hasChildNodes=node.ChildNodes.Count>0;
            string _navigateimgSrc = string.IsNullOrEmpty(node.ImageUrl) ? this.defaultNavigateImageUrl : node.ImageUrl;
            string _titleimgSrc = string.IsNullOrEmpty(node.ImageUrl) ? this.defaultTilteImageUrl : node.ImageUrl;
            string _target = string.IsNullOrEmpty(node.Target) ? defaultTarget : node.Target;
            string _imgTooltip = string.Empty;
            string _tooltop = string.Empty;

            if (!string.IsNullOrEmpty(node.ImageToolTip))
                _imgTooltip = " title=\""+node.ImageToolTip+"\" ";
            if (!string.IsNullOrEmpty(node.ToolTip))
                _tooltop =  " title=\""+node.ToolTip+"\" ";

            if (node.Depth == 1 || hasChildNodes)
            {
                string _text;
                if (string.IsNullOrEmpty(node.NavigateUrl))
                    _text = node.Text;
                else
                    _text="<a href=\"" + node.NavigateUrl + "\" target=\""+_target+"\" "+_tooltop+" > " + node.Text + "</a>";

                string _header = "<div class=\"accordion-item\">"
                    + "<div class=\"accordion-header\">"
                    + "<img src=\"" + this.ResolveClientUrl(_titleimgSrc) + "\" "+_imgTooltip+" />"
                    + _text 
                    + "</div>";
                writer.Write(_header);
                if (hasChildNodes)
                    writer.Write("<div class=\"accordion-content\" >");
            }
            else
            {
                string _menu_item;
                if (string.IsNullOrEmpty(node.NavigateUrl))
                    _menu_item = node.Text;
                else
                    _menu_item = "<div class=\"accordion-menu-item\">"
                        + "<img src=\"" + this.ResolveClientUrl(_navigateimgSrc) + "\" "+_imgTooltip+" />"
                        + "<a href=\"" + node.NavigateUrl + "\" target=\"" + _target + "\" "+_tooltop+" > " + node.Text + "</a></div>";
                writer.Write(_menu_item);
            }
            if (hasChildNodes)
                RenderNodeCollection(writer, node.ChildNodes);

            if (node.Depth == 1 || hasChildNodes)
            {
                if (hasChildNodes)
                    writer.Write("</div></div>");
                else
                    writer.Write("</div>");
            }
        }

        protected override void OnPreRender(EventArgs e)
        {
            string js = "jQuery(\"#"+this.ClientID+"\").accordion("+this.ToKeyValue()+");";
            this.Page.ClientScript.RegisterStartupScript(typeof(Accordion), this.UniqueID, js, true);

            base.OnPreRender(e);
        }

        private string ToKeyValue()
        {
            string strReturn = "";
            strReturn = JSONSettingUtil.ToKeyValue(ht);
            if (string.IsNullOrEmpty(strReturn))
                return "";
            else
                return "{" + strReturn + "}";
        }

    }
}
